#include <vector>
using namespace std;
#include <set>
#include <algorithm>


// version 1
//双指针 + 三数之和
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ret;
        if(nums.size() < 4) return ret;
        //在三数之和上进行叠加！
        
        std::sort(nums.begin(), nums.end());

        //1.先找到四数之和的其中一个
        for(int i = 0; i < nums.size() - 3; ++i){
            long long target_three = target - nums[i];
            //从后序的位置开始找三数之和为 target_three的
            for(int j = i + 1; j < nums.size() - 2; ++j){
                //开始找两数之和！
                long long target_two = target_three - nums[j];
                int left = j + 1, right = nums.size() - 1;
                while(left < right){
                    int sum = nums[left] + nums[right];
                    if(sum > target_two) --right;
                    else if(sum < target_two) ++left;
                    else{
                        ret.push_back({nums[i],nums[j], nums[left], nums[right]});
                        //略过所有相同的
                        long long leftnum = nums[left], rightnum = nums[right];
                        while(left < right && nums[left] == leftnum) ++left;
                        while(left < right && nums[left] == rightnum) --right; 
                    }
                }
                //找完三数之和后，也是一样的，把找过的给略过
                while(j < nums.size() - 2 && nums[j + 1] == nums[j]) ++j;
            }
            //最外层这里，也可能有相同的数字需要略过
            while(i < nums.size() - 3 && nums[i + 1] == nums[i]) ++i;
        }
        return ret;
    }
};

